/*
 * Copyright (c) 2013-2015 Charkey. All rights reserved.
 *
 * This software is the confidential and proprietary information of Charkey.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the agreements you entered into with Charkey.
 *
 * Charkey MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 *
 * Charkey SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package cn.simastudio.talos.inter.controller.api;

import cn.simastudio.talos.common.constants.ApiStatusCode;
import cn.simastudio.talos.common.model.JsonResult;
import cn.simastudio.talos.common.utils.ExceptionUtils;
import cn.simastudio.talos.core.exception.auth.InvalidCaptchaException;
import cn.simastudio.talos.inter.model.inst.Member;
import cn.simastudio.talos.inter.service.inst.MemberService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;

/**
 * Usage: 会员相关api接口
 *
 * @author Charkey
 * @date 2015/6/6 11:31
 */
@RestController
@RequestMapping("/api/members")
public class MemberApiController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MemberApiController.class);

    @Autowired
    private MemberService memberService;

    @Autowired
    private CacheManager cacheManager;

    private Cache telCaptchaCache;

    @PostConstruct
    public void afterPropertiesSet() {
        telCaptchaCache = cacheManager.getCache("telCaptchaCache");
    }

    /**
     * 接口名称：会员注册<br/>
     * 接口地址：POST /api/members/register<br/>
     * 注意：本接口已设置为不需要权限即可访问
     *
     * @param member 待注册会员
     * @return 注册结果：注册成功会返回已注册的会员信息，失败返回错误信息
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public Object register(@ModelAttribute Member member, @RequestParam(value = "captcha", required = false) String captcha) {
        Cache.ValueWrapper captchaValue = telCaptchaCache.get(member.getTel());
        String captchaOfTel = captchaValue != null ? (String) captchaValue.get() : "";
        if (captchaOfTel != null && !captchaOfTel.contains(captcha)) {
            throw new InvalidCaptchaException(captcha);
        }
        try {
            member = memberService.createMember(member);
            // 失效 手机号-验证码 缓存
            if (telCaptchaCache.get(member.getTel()) != null) {
                telCaptchaCache.evict(member.getTel());
            }
            return member;
        } catch (Exception e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("Member registered failed! Reason: {}", e);
            }
            JsonResult result = new JsonResult();
            result.setCode(ApiStatusCode.GENERAL_EXCEPTION);
            result.setMessage("Member registered failed!");
            result.setDevelopMessage(ExceptionUtils.getExceptionMessage(e));
            return result;
        }
    }

    /**
     * 接口名称：通过手机号获得会员信息<br/>
     * 接口地址：GET /api/members/{tel}
     *
     * @param tel 手机号
     * @return 会员信息，失败返回错误信息
     */
    @RequestMapping(value = "/{tel:\\d{11}}", method = RequestMethod.GET)
    public Object getMemberByTel(@PathVariable("tel") String tel) {
        Member member = memberService.getMemberByName(tel);
        if (member != null) {
            return member;
        } else {
            JsonResult result = new JsonResult();
            result.setCode(ApiStatusCode.DATA_NOT_EXISTS);
            result.setMessage("No member can be identified by given tel");
            return result;
        }
    }

    /**
     * 接口名称：重置会员密码<br/>
     * 接口地址：GET /api/members/{tel}/password/restore<br/>
     * 注意：本接口已设置为不需要权限即可访问
     *
     * @param tel 手机号
     * @return 重置密码结果
     */
    @RequestMapping(value = "/{tel}/password/restore", method = RequestMethod.POST)
    public JsonResult restorePassword(@PathVariable("tel") String tel,
                                      @RequestParam("captcha") String captcha) {
        Cache.ValueWrapper captchaValue = telCaptchaCache.get(tel);
        String captchaOfTel = captchaValue != null ? (String) captchaValue.get() : "";
        if (captchaOfTel != null && !captchaOfTel.contains(captcha)) {
            throw new InvalidCaptchaException(captcha);
        }
        Member member = memberService.resetPassword(tel);
        // 失效 手机号-验证码 缓存
        if (telCaptchaCache.get(tel) != null) {
            telCaptchaCache.evict(tel);
        }
        if (member != null) {
            JsonResult result = new JsonResult();
            result.setCode(ApiStatusCode.ACCEPTED);
            result.setData(member.getPassword());
            return result;
        } else {
            JsonResult result = new JsonResult();
            result.setCode(ApiStatusCode.DATA_NOT_EXISTS);
            result.setMessage("No member can be identified by given tel");
            return result;
        }
    }

    /**
     * 接口名称：更改会员密码<br/>
     * 接口地址：GET /api/members/{tel}/password/change<br/>
     *
     * @param tel 手机号
     * @return 更改密码结果
     */
    @RequestMapping(value = "/{tel}/password/change", method = RequestMethod.POST)
    public JsonResult resetPassword(@PathVariable("tel") String tel,
                                    @RequestParam("old_password") String oldPassword,
                                    @RequestParam("new_password") String newPassword) {
        try {
            Member member = memberService.changePassword(tel, oldPassword, newPassword);
            if (member != null) {
                JsonResult result = new JsonResult();
                result.setCode(ApiStatusCode.ACCEPTED);
                result.setData(newPassword);
                return result;
            }
        } catch (Exception e) {
            JsonResult result = new JsonResult();
            result.setCode(ApiStatusCode.UNAUTHORIZED);
            result.setMessage("Old password incorrect");
            return result;
        }
        return null;
    }

}
